package com.psmz.mqim.service;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;

import org.xml.sax.SAXException;

import com.ibm.mq.MQException;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;
import com.psmz.mqim.model.IMMessage;
import com.psmz.mqim.settings.MQSeriesSettings;

/**
 * Obsluga wysylania i odbioru wiadomosci.
 * 
 * @author piotrs10
 * 
 */
public class InstantMessaging {

	private MQSeriesSettings settings;

	public InstantMessaging(MQSeriesSettings settings) {
		this.settings = settings;
	}

	/**
	 * Wysyla wiadomosc
	 * 
	 * @param message
	 *            Wiadomosc.
	 * @throws MQException
	 * @throws XMLStreamException
	 * @throws IOException
	 */
	public void sendInstantMessage(IMMessage message) throws MQException,
			IOException, XMLStreamException {
		int openOptions = CMQC.MQOO_INQUIRE + CMQC.MQOO_FAIL_IF_QUIESCING
				+ CMQC.MQOO_INPUT_SHARED + CMQC.MQOO_OUTPUT;
		MQQueue queue = null;
		MQQueueManager manager = null;
		try {
			manager = new MQQueueManager(settings.getQueueManager());
			MQPutMessageOptions putMessageOptions = new MQPutMessageOptions();
			MQMessage mqMessage = new MQMessage();
			mqMessage.writeString(message.toXml());
			queue = manager.accessQueue(settings.getSendQueueName(),
					openOptions);
			queue.put(mqMessage, putMessageOptions);
		} finally {
			if (queue != null) {
				queue.close();
			}

			if (manager != null) {
				manager.disconnect();
			}
		}

	}

	/**
	 * Odbiera wiadomosc.
	 * 
	 * @return Wiadomosc.
	 * @throws NoMessageException
	 * @throws MQException
	 * @throws IOException
	 * @throws SAXException
	 * @throws ParserConfigurationException
	 */
	public IMMessage receive() throws NoMessageException, MQException,
			IOException, ParserConfigurationException, SAXException {
		int openOptions = CMQC.MQOO_INQUIRE + CMQC.MQOO_FAIL_IF_QUIESCING
				+ CMQC.MQOO_INPUT_SHARED;
		MQQueue queue = null;
		MQQueueManager manager = null;
		IMMessage receivedIMmessage = null;
		try {
			manager = new MQQueueManager(settings.getQueueManager());
			queue = manager.accessQueue(settings.getSendQueueName(),
					openOptions);
			MQMessage mqMessage = new MQMessage();
			queue.get(mqMessage);
			byte[] messageBytes = new byte[mqMessage.getMessageLength()];
			mqMessage.readFully(messageBytes);
			String xmlcontent = new String(messageBytes);
			receivedIMmessage = IMMessage.create(xmlcontent);
		} catch (MQException e) {
			if (e.reasonCode == MQSeriesErrorCodes.MQRC_NO_MSG_AVAILABLE) {
				// brak wiadomosci wyrzucamy no message
				throw new NoMessageException(e);
			} else {
				throw e;
			}
		} finally {
			if (queue != null) {
				queue.close();
			}

			if (manager != null) {
				manager.disconnect();
			}
		}
		return receivedIMmessage;
	}

}
